use axum::{http::{HeaderValue, StatusCode}, response::{IntoResponse, Response}};

use crate::error::{AppErr, ErrorWrap};

use super::header::{self};


pub mod cbor;
pub mod error;



#[inline(always)]
pub fn make_response<F: FnOnce() -> Result<Response, AppErr>>(cb: F) -> Response {
    if let Ok(resp) = cb() {
        resp
    } else {
        let mut resp = StatusCode::OK.into_response();
        resp.headers_mut().insert(header::API_RESP, header::VAL_API_PANIC);
        resp
    }
}

pub struct Void;

impl IntoResponse for Void {

    fn into_response(self) -> Response {
        let mut resp = StatusCode::OK.into_response();
        resp.headers_mut().insert(header::API_RESP, header::VAL_API_OK);
        resp
    }
}

pub struct DownloadFile {
    name: String,
    body: Box<[u8]>,
}

pub fn new_download(name: String, body: Box<[u8]>) -> DownloadFile {
    DownloadFile { name, body }
}

impl IntoResponse for DownloadFile {

    fn into_response(self) -> Response {
        make_response(|| {
            let mut resp = self.body.into_response();
            resp.headers_mut().insert(header::API_RESP, header::VAL_API_OK);
            let file = format!(r#"attachment; filename="{}""#, self.name);
            resp.headers_mut().insert("Content-Disposition", HeaderValue::from_str(&file).wrap()?);
            Ok(resp)
        })
    }
}

